﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Net.Mail;
using System.Net;
using System.Drawing;

namespace distrilan
{
  /// <summary>
  /// Funzioni di gestione del carrello
  /// </summary>
  public partial class Carrello
  {
    //mettendo -1 il carrello quando un utente esce viene cancellato e non se ne tiene memoria, (in pratica alla nuova log in vengono cancellati tutti gli ordini di un cliente
    //la memorizzazione dell'ordine ce la faremo pagare
    public const int GIORNIVALIDITA = -1;
    
    /// <summary>
    /// Consente di inserire un articolo dentro il carrello se è già dentro modifica la quantita
    /// </summary>
    /// <param name="codart"></param>
    /// <param name="quantita"></param>
    /// <param name="prezzo"></param>
    public static void Put( String codart, String quantita, String prezzo )
    {
      // Per prima cosa verifico che l'utente sia riconoscibile
      if (SiteUser.IsLogged() != true){
        Utility.WriteLog("ERRORE", "Carrello.Put", "Utente non loggato, impossibile completare l'operazione", "", "");
        throw new Exception("Utente non loggato, impossibile completare l'operazione");
      }
      
      SqlConnection connection = new SqlConnection(Utility.GetDBConnectionString());
      try{
        connection.Open();
        String sql = "SELECT COUNT(*) FROM articolo WHERE codart='"+codart+"'";
        SqlCommand cmd = new SqlCommand(sql, connection);
        
        // Poi verifico che l'articolo esista davvero in archivio
        if( Convert.ToInt32(cmd.ExecuteScalar())<=0 )
          throw new Exception("L'articolo indicato non è presente in archivio");        
        
        // Verifico che la quantita e il prezzo siano due valori numerici validi
        float qta = float.Parse(quantita);
        float prz = float.Parse(prezzo);

        // Se arrivo qui tutto ok, posso scrivere nel DB però devo controllare se questo articolo è già in carrello
        bool update = false; double oldQta = 0;
        sql = "SELECT * FROM carrello WHERE codart='"+codart+"' AND username='"+SiteUser.getUser().Username+"'";          
        SqlDataAdapter adapter = new SqlDataAdapter();
        adapter.SelectCommand = new SqlCommand(sql, connection);         
        DataSet ds = new DataSet();
        adapter.Fill(ds);
        if (ds.Tables[0].Rows.Count > 0)
        {
          update = true;
          oldQta = float.Parse(ds.Tables[0].Rows[0]["quantita"].ToString());
        }        

        // Ok ora scrivo
        if (update == false)
        {

          String dataa = Utility.GetDateTimeInternationalFormat(DateTime.Now.ToString());

          sql = Utility.GetDateFormatInstruction();
          sql += "INSERT INTO carrello(datainsert,username,codart,quantita,prezzo) VALUES (";
          sql += "'" + Utility.GetDateTimeInternationalFormat(DateTime.Now.ToString()) + "','" + SiteUser.getUser().Username + "',";
          //sql += "'" + DateTime.Now.ToShortDateString() + "','" + SiteUser.getUser().Username + "',";
          sql += "'" + codart + "'," + Utility.GetDoubleForDB(qta) + "," + prz.ToString().Replace(",",".") + ")";
          //sql += "'" + codart + "'," + qta + "," + prz + ")";
          cmd = new SqlCommand(sql, connection);
          cmd.ExecuteNonQuery();
        }
        else
        {
          String dataa = Utility.GetDateTimeInternationalFormat(DateTime.Now.ToString());
          sql = "UPDATE carrello SET datainsert='" + Utility.GetDateTimeInternationalFormat(DateTime.Now.ToString()) + "', quantita=" + Utility.GetDoubleForDB(qta+oldQta)+ " WHERE username='"+SiteUser.getUser().Username+"' AND codart='"+codart+"'";
          //sql = "UPDATE carrello SET datainsert='" + DateTime.Now.ToShortDateString() + "', quantita=" + Utility.GetDoubleForDB(qta + oldQta) + " WHERE username='" + SiteUser.getUser().Username + "' AND codart='" + codart + "'";
          cmd = new SqlCommand(sql, connection);
          cmd.ExecuteNonQuery();
        }
          
      }
      catch (Exception ex)
      {
        Utility.WriteLog("ERRORE", "Carrello.Put", ex.Message, SiteUser.getUser().Username, "");
        throw ex;
      }
      finally
      {
        connection.Close();
      }

    }

    /// <summary>
    /// Cancella un articolo dal carrello
    /// </summary>
    /// <param name="codart"></param>
    public static void Remove(String codart)
    {
      // Per prima cosa verifico che l'utente sia riconoscibile
      if (SiteUser.IsLogged() != true)
      {
        Utility.WriteLog("ERRORE", "Carrello.Remove", "Utente non loggato, impossibile completare l'operazione", "", "");
        throw new Exception("Utente non loggato, impossibile completare l'operazione");
      }


      SqlConnection connection = new SqlConnection(Utility.GetDBConnectionString());
      try
      {
        connection.Open();
        // Cancello l'articolo dal carrello        
        String sql = "DELETE FROM carrello WHERE username='" + SiteUser.getUser().Username + "' AND codart='" + codart + "'";
        SqlCommand cmd = new SqlCommand(sql, connection);
        cmd.ExecuteNonQuery();        
      }
      catch (Exception ex)
      {
        Utility.WriteLog("ERRORE", "Carrello.Remove", ex.Message, SiteUser.getUser().Username, "");
        throw;
      }
      finally
      {
        connection.Close();
      }
    }

    /// <summary>
    /// Consente di modificare la quantità di un articolo del carrello
    /// </summary>
    /// <param name="codart"></param>
    /// <param name="newQta"></param>
    public static void UpdateQta(String codart, String newQta)
    {
      // Per prima cosa verifico che l'utente sia riconoscibile
      if (SiteUser.IsLogged() != true)
      {
        Utility.WriteLog("ERRORE", "Carrello.UpdateQta", "Utente non loggato, impossibile completare l'operazione", "", "");
        throw new Exception("Utente non loggato, impossibile completare l'operazione");
      }


      SqlConnection connection = new SqlConnection(Utility.GetDBConnectionString());
      try
      {
        connection.Open();
        String sql = "SELECT COUNT(*) FROM articoli WHERE codart='" + codart + "'";
        SqlCommand cmd = new SqlCommand(sql, connection);

        // Controllo che la quantità passata sia valida
        double qta = Double.Parse(newQta);

        // Verifico che l'articolo sia effettivamente nel carrello        
        sql = "SELECT COUNT(*) FROM carrello WHERE codart='" + codart + "' AND username='" + SiteUser.getUser().Username + "'";
        cmd = new SqlCommand(sql, connection);
        int c = Convert.ToInt32(cmd.ExecuteScalar());
        if (c > 0)
        {
          // Se c'è updato la quantità  
          sql = "UPDATE carrello SET datainsert='" + Utility.GetDateTimeInternationalFormat(DateTime.Now.ToString()) + "', quantita=" + Utility.GetDoubleForDB( qta ) + " WHERE username='" + SiteUser.getUser().Username + "' AND codart='" + codart + "'";
          cmd = new SqlCommand(sql, connection);
          cmd.ExecuteNonQuery();
        }                

      }
      catch (Exception ex)
      {
        Utility.WriteLog("ERRORE", "Carrello.UpdateQta", ex.Message, SiteUser.getUser().Username, "");
        throw ex;
      }
      finally
      {
        connection.Close();
      }
    }

    /// <summary>
    /// Svuota il carrello di un determinato utente
    /// </summary>
    public static void Svuota()
    {
      // Per prima cosa verifico che l'utente sia riconoscibile
      if (SiteUser.IsLogged() != true)
      {
        Utility.WriteLog("ERRORE", "Carrello.Svuota", "Utente non loggato, impossibile completare l'operazione", "", "");
        throw new Exception("Utente non loggato, impossibile completare l'operazione");
      }


      SqlConnection connection = new SqlConnection(Utility.GetDBConnectionString());
      try
      {
        connection.Open();
        // Cancello tutto dal carrello     
        String sql = "DELETE FROM carrello WHERE username='" + SiteUser.getUser().Username + "'";
        SqlCommand cmd = new SqlCommand(sql, connection);
        cmd.ExecuteNonQuery();
      }
      catch (Exception ex)
      {
        Utility.WriteLog("ERRORE", "Carrello.Svuota", ex.Message, SiteUser.getUser().Username, "");
        throw ex;
      }
      finally
      {
        connection.Close();
      }
    }

    /// <summary>
    /// Verifica se ci sono nel carrello degli articoli inseriti con data anteriore a quella specificata da una 
    /// costante e se è cosi elimina gli articoli presenti
    /// </summary>
    public static void ControllaCarrello()
    {
      // Per prima cosa verifico che l'utente sia riconoscibile
      if (SiteUser.IsLogged() != true)
      {
        Utility.WriteLog("ERRORE", "Carrello.ControllaCarrello", "Utente non loggato, impossibile completare l'operazione", "", "");
        throw new Exception("Utente non loggato, impossibile completare l'operazione");
      }

      SqlConnection connection = new SqlConnection(Utility.GetDBConnectionString());
      try
      {
        connection.Open();
        // Cancello tutto dal carrello     
        String sql = "DELETE FROM carrello WHERE username='" + SiteUser.getUser().Username + "' AND DATEDIFF(day, datainsert,'"+Utility.GetDateTimeInternationalFormat(DateTime.Now.ToString())+"')>"+GIORNIVALIDITA;
        SqlCommand cmd = new SqlCommand(sql, connection);
        cmd.ExecuteNonQuery();
      }
      catch (Exception ex)
      {
        Utility.WriteLog("ERRORE", "Carrello.Svuota", ex.Message, SiteUser.getUser().Username, "");
        //throw ex;
      }
      finally
      {
        connection.Close();
      }
    }



    /// <summary>
    /// 
    /// </summary>
    public static void EvadiOrdine(string NotaOrdine)
    {

      // Per prima cosa verifico che l'utente sia riconoscibile
      if (SiteUser.IsLogged() != true)
      {
        Utility.WriteLog("ERRORE", "Carrello.EvadiOrdine", "Utente non loggato, impossibile completare l'operazione", "", "");
        throw new Exception("Utente non loggato, impossibile completare l'operazione");
      }

      SqlConnection connection = new SqlConnection(Utility.GetDBConnectionString());
      SqlTransaction tr = null;
      try
      {
        connection.Open();
        tr = connection.BeginTransaction();
        // Controllo che nel carrello ci sia qualcosa
        
        //String sql = "SELECT * FROM carrello WHERE username='" + SiteUser.getUser().Username + "'";

        String sql = "SELECT C.id, C.datainsert, C.username, C.codart, C.quantita, C.prezzo, A.descri, A.prezzo AS PrezzoListino FROM carrello C, articolo A WHERE username='" + SiteUser.getUser().Username + "' AND C.codart = A.codart";

        SqlDataAdapter adapter = new SqlDataAdapter();
        adapter.SelectCommand = new SqlCommand(sql, connection);
        adapter.SelectCommand.Transaction = tr;          
        DataSet ds = new DataSet();
        adapter.Fill(ds);
        if (ds.Tables[0].Rows.Count == 0)                
          throw new Exception("Impossibile completare l'operazione il carrello è vuoto");
        
        // Leggo l'ultimo numero di vendita effettuato
        sql = "SELECT MAX(nvendita) FROM storicovendite";
        SqlCommand cmd = new SqlCommand(sql, connection);
        cmd.Transaction = tr;
        int max = 0;
        try{
          max = Convert.ToInt32(cmd.ExecuteScalar());
        }catch(Exception){}
        max++;

        // Ora scrivo i dati della vendita nello storico vendite

        foreach (DataRow row in ds.Tables[0].Rows)
        {
          String prezzo = Convert.ToString(row["prezzo"]);
          sql = Utility.GetDateFormatInstruction();
          sql += "INSERT INTO storicovendite(nvendita,data,username,codart,quantita,prezzo) VALUES ";
          sql +="("+max+",'"+Utility.GetDateTimeInternationalFormat(DateTime.Now.ToString())+"','"+SiteUser.getUser().Username+"','"+row["codart"].ToString().Trim()+"',"+row["quantita"]+","+row["prezzo"].ToString().Replace(",",".")+")";
          cmd = new SqlCommand(sql, connection);
          cmd.Transaction = tr;
          cmd.ExecuteNonQuery();
        }

        // Infine cancello i dati dal carrello
        // Cancello tutto dal carrello     
        sql = "DELETE FROM carrello WHERE username='" + SiteUser.getUser().Username + "'";
        cmd = new SqlCommand(sql, connection);
        cmd.Transaction = tr;
        cmd.ExecuteNonQuery();

        // Preparazione invio e-mail di conferma ordine
        InviaMail(ds.Tables[0], max, NotaOrdine);

        // Eseguo tutto
        tr.Commit();
      }
      catch (Exception ex)
      {
        if (tr != null) tr.Rollback();
        Utility.WriteLog("ERRORE", "Carrello.EvadiOrdine", ex.Message, SiteUser.getUser().Username, "");
        throw ex;
      }
      finally
      {
        connection.Close();
      }
    }


    /// <summary>
    /// Restituisce una data table con il contenuto attuale del carrello
    /// </summary>
    /// <returns></returns>
    public static DataTable LeggiCarrello()
    {
      // Per prima cosa verifico che l'utente sia riconoscibile
      if (SiteUser.IsLogged() != true)
      {
        Utility.WriteLog("ERRORE", "Carrello.LeggiCarrello", "Utente non loggato, impossibile completare l'operazione", "", "");
        throw new Exception("Utente non loggato, impossibile completare l'operazione");
      }
      
      SqlConnection connection = new SqlConnection(Utility.GetDBConnectionString());      
      try
      {
        connection.Open();                
        String sql = "SELECT * FROM carrello WHERE username='" + SiteUser.getUser().Username + "'";
        SqlDataAdapter adapter = new SqlDataAdapter();
        adapter.SelectCommand = new SqlCommand(sql, connection);        
        DataSet ds = new DataSet();
        adapter.Fill(ds);

        return ds.Tables[0];
      }
      catch (Exception ex)
      {        
        Utility.WriteLog("ERRORE", "Carrello.LeggiCarrello", ex.Message, SiteUser.getUser().Username, "");
        throw ex;
      }
      finally
      {
        connection.Close();
      }      
    }


    /// <summary>
    /// Invia le email di conferma di acquisto (DA IMPLEMENTARE)
    /// </summary>
    private static void InviaMail( DataTable tab, int numOrdine, string NotaOrdine )
    {
      NotaOrdine = NotaOrdine.Replace("\r\n","<br/>");

      //mail alla quale inviare gli ordini di distrilan ordini@distrilan.it <ordini@distrilan.it>
      String messaggio = "Ricevuto ordine n." + numOrdine + " dal cliente " + SiteUser.getUser().Nome + " (Username:" + SiteUser.getUser().Username + ")<br/><br/>";

      double totaleOrdine = 0;
      
      // Ora scrivo i dati della vendita nello storico vendite
      //è in questo ciclo che dovrei 

      //dichiaro tabella, celle e riga
      Table tabellaOrdine = new Table();

      //setto alcuni stili della tabella
      tabellaOrdine.ControlStyle.BorderWidth = Unit.Pixel(2);
      tabellaOrdine.ControlStyle.BorderColor = Color.Black;

      //dichiaro le celle che mi serviranno
      TableCell cellaCodice = new TableCell();
        cellaCodice.Width = Unit.Pixel(150);
      TableCell cellaDescrizione = new TableCell();
      TableCell cellaQta = new TableCell();
      TableCell cellaPrezzo = new TableCell();
      TableCell cellaPrezzoScontato = new TableCell();
      TableCell cellaPrezzoScontatoQta = new TableCell();

      //alle celle aggiungo il test che mi serve inserire
      cellaCodice.Controls.Add(new LiteralControl("<strong>Codice</strong>"));
      cellaDescrizione.Controls.Add(new LiteralControl("<strong>Descrizione</strong>"));
      cellaQta.Controls.Add(new LiteralControl("<strong>Qta</strong>"));
      cellaPrezzo.Controls.Add(new LiteralControl("<strong>Prezzo</strong>"));
      cellaPrezzoScontato.Controls.Add(new LiteralControl("<strong>Prezzo Scontato</strong>"));
      cellaPrezzoScontatoQta.Controls.Add(new LiteralControl("<strong>Prezzo Scontato Qta</strong>"));

      //creo la e gli aggiungo le varie celle
      TableRow riga = new TableRow();

      riga.Controls.Add(cellaCodice);
      riga.Controls.Add(cellaDescrizione);
      riga.Controls.Add(cellaQta);
      riga.Controls.Add(cellaPrezzo);
      riga.Controls.Add(cellaPrezzoScontato);
      riga.Controls.Add(cellaPrezzoScontatoQta);

      //aggiungo a riga alla tabella 
      tabellaOrdine.Controls.Add(riga);

      foreach (DataRow row in tab.Rows)
      {
        riga = new TableRow();
        
        //creo le celle e le formatto 
        cellaCodice = new TableCell();
        cellaCodice.BorderWidth = Unit.Pixel(1);
        cellaDescrizione = new TableCell();
        cellaDescrizione.BorderWidth = Unit.Pixel(1);
        cellaQta = new TableCell();
        cellaQta.BorderWidth = Unit.Pixel(1);
        cellaPrezzo = new TableCell();
        cellaPrezzo.BorderWidth = Unit.Pixel(1);
        cellaPrezzoScontato = new TableCell();
        cellaPrezzoScontato.BorderWidth = Unit.Pixel(1);
        cellaPrezzoScontatoQta = new TableCell();
        cellaPrezzoScontatoQta.BorderWidth = Unit.Pixel(1);

        Double prezzo = Convert.ToDouble(row["prezzo"]);
        int quantita = Convert.ToInt32(row["quantita"]);
        double przXqta = Math.Round(prezzo * quantita, 2, MidpointRounding.AwayFromZero);
        string codart = row["codart"].ToString().Trim();
        string descrizione = row["descri"].ToString().Trim();
        Double PrezzoListino = Convert.ToDouble(row["PrezzoListino"]);

        //riempio le colonne della riga
        cellaCodice.Controls.Add(new LiteralControl(codart));
        cellaDescrizione.Controls.Add(new LiteralControl(descrizione));
        cellaQta.Controls.Add(new LiteralControl(quantita.ToString()));
        cellaPrezzo.Controls.Add(new LiteralControl(Utility.formattaPrezzo(PrezzoListino.ToString())));
        cellaPrezzoScontato.Controls.Add(new LiteralControl(Utility.formattaPrezzo(prezzo.ToString())));
        cellaPrezzoScontatoQta.Controls.Add(new LiteralControl(Utility.formattaPrezzo(przXqta.ToString())));

        //aggiungo le colonne alla riga
        riga.Controls.Add(cellaCodice);
        riga.Controls.Add(cellaDescrizione);
        riga.Controls.Add(cellaQta);
        riga.Controls.Add(cellaPrezzo);
        riga.Controls.Add(cellaPrezzoScontato);
        riga.Controls.Add(cellaPrezzoScontatoQta);

        //aggiungo lo stile per centrare il testo
        cellaCodice.Style.Add("text-align", "left");
        cellaDescrizione.Style.Add("text-align", "left");
        cellaQta.Style.Add("text-align", "center");
        cellaPrezzo.Style.Add("text-align", "center");
        cellaPrezzoScontato.Style.Add("text-align", "center");
        cellaPrezzoScontatoQta.Style.Add("text-align", "center");

        //aggiungo la riga alla tabella
        tabellaOrdine.Rows.Add(riga);

        //messaggio += "Articolo: " + row["codart"].ToString().Trim() + ", Quantita:" + quantita + ", Prezzo scontato:" + prezzo + " prezzo scontato per quantita (arrotondato):" + przXqta + "<br/>";
        totaleOrdine = totaleOrdine + (quantita * prezzo);
      }

      //formatto il controllo HTML per essere inserito nell'output ad html
      StringBuilder sb = new StringBuilder();
      StringWriter sw = new StringWriter(sb);
      HtmlTextWriter htw = new HtmlTextWriter(sw);
      tabellaOrdine.RenderControl(htw);

      //aggiungo la tabella al messaggio di output
      messaggio += sb.ToString();

      totaleOrdine = Math.Round(totaleOrdine, 2, MidpointRounding.AwayFromZero);
      messaggio += " <br/><br/><br/> <strong>TOTALE ORDINE:</strong>" + Utility.formattaPrezzo(totaleOrdine.ToString().Trim());
      messaggio += "<br/><br/><br/>";
      messaggio += "<strong>NOTE ORDINE:</strong><br/>";
      messaggio += NotaOrdine;
                  
      //MailMessage distrilanMail = new MailMessage("from","to","Ordine da Sito web",messaggio);
      MailMessage mailMsg = new MailMessage();
      mailMsg.IsBodyHtml = true;
      mailMsg.Body += messaggio;

      mailMsg.From = new MailAddress("ordini@distrilan.it");
      mailMsg.To.Add(new MailAddress("ordini@distrilan.it"));
      mailMsg.To.Add(new MailAddress(SiteUser.getUser().Email));
      mailMsg.Subject = "Ordine da Sito web";

      SmtpClient smtp = new SmtpClient("mail.distrilan.it");
      NetworkCredential Credential = new NetworkCredential("ordini@distrilan.it", "postadistrilan");
      smtp.Credentials = Credential;
     
      //tento l'invio della mail
      try{
        smtp.Send(mailMsg);
      }
      catch (Exception ex)
      {
        Utility.WriteLog("ERRORE", "Carrello.InviaMail", ex.Message, SiteUser.getUser().Username, "");
        throw ex;
      }
    }
  }
}